import { createElement } from 'react';
import dynamic from 'dva/dynamic';
import pathToRegexp from 'path-to-regexp';
import { getMenuData } from './menu';
import { getAuthority } from '../utils/authority';

let routerDataCache;
const authArray = getAuthority().split(',');

const modelNotExisted = (app, model) =>
  // eslint-disable-next-line
  !app._models.some(({ namespace }) => {
    return namespace === model.substring(model.lastIndexOf('/') + 1);
  });

// wrapper of dynamic
const dynamicWrapper = (app, models, component) => {
  // () => require('module')
  // transformed by babel-plugin-dynamic-import-node-sync
  if (component.toString().indexOf('.then(') < 0) {
    models.forEach(model => {
      if (modelNotExisted(app, model)) {
        // eslint-disable-next-line
        app.model(require(`../models/${model}`).default);
      }
    });
    return props => {
      if (!routerDataCache) {
        routerDataCache = getRouterData(app);
      }
      return createElement(component().default, {
        ...props,
        routerData: routerDataCache,
      });
    };
  }
  // () => import('module')
  return dynamic({
    app,
    models: () =>
      models.filter(model => modelNotExisted(app, model)).map(m => import(`../models/${m}.js`)),
    // add routerData prop
    component: () => {
      if (!routerDataCache) {
        routerDataCache = getRouterData(app);
      }
      return component().then(raw => {
        const Component = raw.default || raw;
        return props =>
          createElement(Component, {
            ...props,
            routerData: routerDataCache,
          });
      });
    },
  });
};

function getFlatMenuData(menus) {
  let keys = {};
  menus.forEach(item => {
    if (item.children) {
      keys[item.path] = { ...item };
      keys = { ...keys, ...getFlatMenuData(item.children) };
    } else if (authArray.includes(item.authority) || !item.authority) {
      keys[item.path] = { ...item };
    }
  });
  return keys;
}

export const getRouterData = app => {
  const routerConfig = {
    '/': {
      component: dynamicWrapper(app, ['user', 'login'], () => import('../layouts/BasicLayout')),
    },

    '/dashboard/monitor': {
      component: dynamicWrapper(app, ['monitor'], () => import('../routes/Dashboard/Monitor')),
      authority: 's1_0201',
    },
    '/dashboard/devlist': {
      component: dynamicWrapper(app, ['dev', 'program'], () =>
        import('../routes/Dashboard/DeviceList')
      ),
      authority: 's1_0202',
    },
    '/dashboard/vehperiod': {
      component: dynamicWrapper(app, ['vehicle', 'dev'], () =>
        import('../routes/Dashboard/VehPeriod')
      ),
    },
    '/dashboard/devdetail/:devId': {
      component: dynamicWrapper(app, ['devInfo'], () => import('../routes/Dashboard/DevDetail')),
      authority: 's1_0203',
    },
    '/dashboard/devedit/:devId': {
      component: dynamicWrapper(app, ['dev'], () => import('../routes/Dashboard/DevEdit')),
    },
    '/dashboard/devtask/:devName': {
      component: dynamicWrapper(app, ['devtask'], () => import('../routes/Dashboard/DevTask')),
    },
    '/devmaintain/devtest': {
      component: dynamicWrapper(app, ['devtest'], () => import('../routes/DevMaintain/DevTest')),
    },
    '/devmaintain/devfix': {
      component: dynamicWrapper(app, ['devfix'], () => import('../routes/DevMaintain/DevFix')),
    },
    '/devmaintain/devalarm': {
      component: dynamicWrapper(app, ['devalarm'], () => import('../routes/DevMaintain/DevAlarm')),
    },
    '/devmaintain/devreport': {
      component: dynamicWrapper(app, ['devreport'], () =>
        import('../routes/DevMaintain/DevReport')
      ),
    },
    '/devmaintain/devupdate': {
      component: dynamicWrapper(app, ['devupdate'], () =>
        import('../routes/DevMaintain/DevUpdate')
      ),
    },
    '/devmaintain/repairDet/:repairId': {
      component: dynamicWrapper(app, ['devrepair'], () =>
        import('../routes/DevMaintain/DevFixDetail')
      ),
    },
    '/devmaintain/alarmDet/:alarmId': {
      component: dynamicWrapper(app, ['devalarm'], () =>
        import('../routes/DevMaintain/DevAlarmDet')
      ),
    },

    '/dashboard/devtrack/:devId': {
      component: dynamicWrapper(app, ['traveltrack'], () =>
        import('../routes/Dashboard/TravelTrack')
      ),
    },
    '/dashboard/devtrackbaidu/:devId': {
      component: dynamicWrapper(app, ['traveltrackbaidu'], () =>
        import('../routes/Dashboard/TravelTrackBaidu')
      ),
    },
    '/dashboard/flowlist': {
      component: dynamicWrapper(app, ['flow', 'devtask'], () =>
        import('../routes/Dashboard/FlowList')
      ),
    },
    '/dashboard/simcard': {
      component: dynamicWrapper(app, ['simcard'], () => import('../routes/Dashboard/SimCard')),
    },
    '/dashboard/simcarddetail/:simcardId': {
      component: dynamicWrapper(app, ['simcardDetail'], () =>
        import('../routes/Dashboard/SimCardDetail')
      ),
    },
    // '/dashboard/workplace': {
    //   component: dynamicWrapper(app, ['project', 'activities', 'chart'], () =>
    //     import('../routes/Dashboard/Workplace')
    //   ),
    //   // hideInBreadcrumb: true,
    //   // name: '工作台',
    //   // authority: 'admin',
    // },

    // '/form/step-form': {
    //   component: dynamicWrapper(app, ['form'], () => import('../routes/Forms/StepForm')),
    // },
    // '/form/step-form/info': {
    //   name: '分步表单（填写转账信息）',
    //   component: dynamicWrapper(app, ['form'], () => import('../routes/Forms/StepForm/Step1')),
    // },
    // '/form/step-form/confirm': {
    //   name: '分步表单（确认转账信息）',
    //   component: dynamicWrapper(app, ['form'], () => import('../routes/Forms/StepForm/Step2')),
    // },
    // '/form/step-form/result': {
    //   name: '分步表单（完成）',
    //   component: dynamicWrapper(app, ['form'], () => import('../routes/Forms/StepForm/Step3')),
    // },
    // '/form/advanced-form': {
    //   component: dynamicWrapper(app, ['form'], () => import('../routes/Forms/AdvancedForm')),
    // },
    '/list/table-list': {
      component: dynamicWrapper(app, ['log'], () => import('../routes/List/TableList')),
    },
    '/program/programlist': {
      component: dynamicWrapper(app, ['program', 'monitor'], () =>
        import('../routes/Program/Collections')
      ),
      authority: 's1_0401',
    },
    '/program/playlist': {
      component: dynamicWrapper(app, ['playlist'], () => import('../routes/Program/PlayList')),
      authority: 's1_0401',
    },
    '/program/cutinlist': {
      component: dynamicWrapper(app, ['cutinlist'], () => import('../routes/Program/CutInList')),
    },
    '/program/cutindetail/:icTaskId': {
      component: dynamicWrapper(app, ['cutindetail'], () =>
        import('../routes/Program/CutInDetail')
      ),
    },
    '/matter/matterlib': {
      component: dynamicWrapper(app, ['rule', 'dev'], () => import('../routes/Program/MatterLib')),
      authority: 's1_0301',
    },
    '/matter/cutinlib': {
      component: dynamicWrapper(app, ['cutinlib', 'dev'], () =>
        import('../routes/Program/CutInLib')
      ),
    },

    '/matter/detail/:matId': {
      component: dynamicWrapper(app, ['matdetail'], () =>
        import('../routes/Program/MatterDetail.js')
      ),
    },
    '/program/programdetail/:progId': {
      component: dynamicWrapper(app, ['list'], () => import('../routes/Program/ProgramDetail.js')),
    },

    '/program/arealist': {
      component: dynamicWrapper(app, ['areaInfo', 'monitor'], () =>
        import('../routes/Program/GeoLib')
      ),
    },
    // '/program/tasklist/:progId': {
    //   component: dynamicWrapper(app, ['task'], () => import('../routes/Program/TaskList.js')),
    // },
    '/program/basic-list/:progId': {
      component: dynamicWrapper(app, ['list'], () => import('../routes/Program/BasicList')),
    },
    '/program/programconfig/:progId': {
      component: dynamicWrapper(app, ['list'], () => import('../routes/Program/ProgramConfig')),
    },
    '/program/programmatdet/:progId/:matId': {
      component: dynamicWrapper(app, ['rule', 'promatdet', 'areaInfo'], () =>
        import('../routes/Program/ProgramMatDet')
      ),
    },
    '/program/addcutintask': {
      component: dynamicWrapper(app, ['cutinlib', 'dev'], () =>
        import('../routes/Program/AddCutInTask')
      ),
    },

    '/basic-form/:progId': {
      component: dynamicWrapper(app, ['rule', 'program', 'areaInfo'], () =>
        import('../routes/Program/BasicForm')
      ),
    },
    // '/list/card-list': {
    //   component: dynamicWrapper(app, ['list'], () => import('../routes/List/CardList')),
    // },
    // '/list/search': {
    //   component: dynamicWrapper(app, ['list'], () => import('../routes/List/List')),
    // },
    // '/list/search/projects': {
    //   component: dynamicWrapper(app, ['list'], () => import('../routes/List/Projects')),
    // },
    // '/list/search/applications': {
    //   component: dynamicWrapper(app, ['list'], () => import('../routes/List/Applications')),
    // },
    // '/list/search/articles': {
    //   component: dynamicWrapper(app, ['list'], () => import('../routes/List/Articles')),
    // },
    '/devlog/devtask/:devName': {
      component: dynamicWrapper(app, ['devtask'], () => import('../routes/DevLog/DevTask')),
    },
    '/devlog/tasklist/:progId': {
      component: dynamicWrapper(app, ['task'], () => import('../routes/DevLog/TaskList.js')),
    },
    '/devlog/cutinlog/:progName': {
      component: dynamicWrapper(app, ['cutinlog'], () => import('../routes/DevLog/CutInLog')),
    },
    '/profile/analysis': {
      component: dynamicWrapper(app, ['chart', 'monitor'], () =>
        import('../routes/Dashboard/Analysis')
      ),
    },
    // '/profile/basic': {
    //   component: dynamicWrapper(app, ['profile'], () => import('../routes/Profile/BasicProfile')),
    // },

    // '/profile/advanced': {
    //   component: dynamicWrapper(app, ['profile'], () =>
    //     import('../routes/Profile/AdvancedProfile')
    //   ),
    // },
    // '/result/success': {
    //   component: dynamicWrapper(app, [], () => import('../routes/Result/Success')),
    // },
    // '/result/fail': {
    //   component: dynamicWrapper(app, [], () => import('../routes/Result/Error')),
    // },
    '/exception/403': {
      component: dynamicWrapper(app, [], () => import('../routes/Exception/403')),
    },
    '/exception/404': {
      component: dynamicWrapper(app, [], () => import('../routes/Exception/404')),
    },
    '/exception/500': {
      component: dynamicWrapper(app, [], () => import('../routes/Exception/500')),
    },
    '/exception/trigger': {
      component: dynamicWrapper(app, ['error'], () =>
        import('../routes/Exception/triggerException')
      ),
    },
    '/user': {
      component: dynamicWrapper(app, [], () => import('../layouts/UserLayout')),
    },

    '/user/register': {
      component: dynamicWrapper(app, ['register'], () => import('../routes/User/Register')),
    },
    '/user/register-result': {
      component: dynamicWrapper(app, [], () => import('../routes/User/RegisterResult')),
    },

    '/systemparam/gpsintervaltime': {
      component: dynamicWrapper(app, ['gpsintervaltime'], () =>
        import('../routes/Systemparam/GpsIntervalTime')
      ),
    },
    '/usermanage/resetpwd': {
      component: dynamicWrapper(app, ['gpsintervaltime'], () =>
        import('../routes/UserManage/ResetPwd')
      ),
      authority: 's1_0504',
    },
    '/usermanage/rolemanage': {
      component: dynamicWrapper(app, ['role'], () => import('../routes/UserManage/RoleManage')),
      authority: 's1_0503',
    },
    '/usermanage/acmanage': {
      component: dynamicWrapper(app, ['role', 'account'], () =>
        import('../routes/UserManage/AccountManage')
      ),
      authority: 's1_0502',
    },

    '/usermanage/profile': {
      component: dynamicWrapper(app, ['user'], () => import('../routes/UserManage/Profile')),
      authority: 's1_0501',
    },
    '/usermanage/editaccount/:userName': {
      component: dynamicWrapper(app, ['user', 'auth'], () =>
        import('../routes/UserManage/EditAccount')
      ),
      authority: 's1_0502',
    },
    '/usermanage/addaccount': {
      component: dynamicWrapper(app, ['auth'], () => import('../routes/UserManage/AddAccount')),
    },
    '/usermanage/contactus': {
      component: dynamicWrapper(app, [], () => import('../routes/UserManage/Contact')),
    },

    '/Dashboard/DevAdd': {
      component: dynamicWrapper(app, ['dev'], () => import('../routes/Dashboard/DevAdd')),
    },
    '/user/login': {
      component: dynamicWrapper(app, ['login'], () => import('../routes/User/Login')),
    },
    // '/user/:id': {
    //   component: dynamicWrapper(app, [], () => import('../routes/User/SomeComponent')),
    // },
  };
  // Get name from ./menu.js or just set it in the router data.
  const menuData = getFlatMenuData(getMenuData());

  // Route configuration data
  // eg. {name,authority ...routerConfig }
  const routerData = {};
  // The route matches the menu
  Object.keys(routerConfig).forEach(path => {
    // Regular match item name
    // eg.  router /user/:id === /user/chen
    const pathRegexp = pathToRegexp(path);
    const menuKey = Object.keys(menuData).find(key => pathRegexp.test(`${key}`));
    let menuItem = {};
    // If menuKey is not empty
    if (menuKey) {
      menuItem = menuData[menuKey];
    }
    let router = routerConfig[path];
    // If you need to configure complex parameter routing,
    // https://github.com/ant-design/ant-design-pro-site/blob/master/docs/router-and-nav.md#%E5%B8%A6%E5%8F%82%E6%95%B0%E7%9A%84%E8%B7%AF%E7%94%B1%E8%8F%9C%E5%8D%95
    // eg . /list/:type/user/info/:id
    router = {
      ...router,
      name: router.name || menuItem.name,
      authority: router.authority || menuItem.authority,
      hideInBreadcrumb: router.hideInBreadcrumb || menuItem.hideInBreadcrumb,
    };
    routerData[path] = router;
  });
  return routerData;
};
